﻿#region Using namespaces

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

using BOL.Utils.Optimization.EvolutionaryAlgorithms;
using BOL.Apps.GeneNetworkBrowser.IO;
using BOL.Apps.GeneNetworkBrowser.Analysis.SubNetwork;
using BOL.Apps.GeneNetworkBrowser.Networks;
using BOL.Apps.GeneNetworkBrowser.ViewModels;

#endregion

namespace BOL.Apps.GeneNetworkBrowser.Windows
{
    public partial class SubNetworkWindow : Window
    {
        #region Private variables

        private SubNetworkResult _result;

        #endregion

        #region Public properties

        public SubNetworkResult Result { get { return _result; } }

        #endregion

        #region Constructor

        public SubNetworkWindow()
        {
            InitializeComponent();
        }

        #endregion

        #region Private methods

        private void OK(object sender, RoutedEventArgs args)
        {
            // assigns a background worker
            BackgroundWorker worker = new BackgroundWorker();
            worker.WorkerReportsProgress = true;
            worker.WorkerSupportsCancellation = true;

            // updates algorithm-free parameters from the UI
            Network source = _cbNetworks.SelectedItem as Network;
            var minNodes = (int)_sliderMinNodes.Value;
            var maxNodes = (int)_sliderMaxNodes.Value;
            int seed = DateTime.Now.Millisecond;
            Int32.TryParse(_tbRandomSeed.Text, out seed);
            bool isVerbose = _cbVerbose.IsChecked.Value;
            bool openSubNetworks = _cbOpenSubNetworks.IsChecked.Value;
            
            if (_cbAlgorithmType.SelectedIndex == 0)
            {
                // updates genetic algorithm parameters from the ui;
                double tolerance = 1e-6;
                Double.TryParse(_tbTolerance.Text, out tolerance);
                double crossoverRate = _sliderCrossoverRate.Value;
                double mutationRate = _sliderMutationRate.Value;
                var populationSize = (int)_sliderPopulationSize.Value;
                var numberOfElites = (int)_sliderNumberOfElites.Value;
                var selectionMethod = (SelectionMethod)(_cbSelectionMethod.SelectedItem);
                var numberOfIterations = (int)_sliderNumberOfIterations.Value;

                // applying gene value
                ApplyGeneValue(source, "Cox");
                //ApplyExpressionValue(source);

                // instantiate a sub-network genetic algorithm
                var sngn = new SubNetworkGeneticAlgorithm(new Random(seed), source, minNodes, maxNodes, populationSize, numberOfElites, selectionMethod, crossoverRate, mutationRate, numberOfIterations, true, tolerance, isVerbose, true);

                worker.DoWork += delegate(object s, DoWorkEventArgs e)
                {
                    e.Result = sngn.Analyze();
                };

                worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs e)
                {
                    _result = e.Result as SubNetworkResult;

                    if (e.Cancelled)
                        Console.WriteLine("Cancelled.");
                    else if (e.Error != null)
                        Console.WriteLine("Exception: {0}", e.Error.Message);
                    else
                    {
                        var mw = (MainWindow)Application.Current.MainWindow;
                        var vmmw = mw.DataContext as MainWindowViewModel;
                        //vmmw.SubNetworks = _result.SubNetworks;
                        if (openSubNetworks)
                            mw.OpenSubNetworkResult(_result);

                        DialogResult = true;
                    }
                };

                worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs e)
                {
                    int percentage = e.ProgressPercentage;
                };

                worker.RunWorkerAsync();
                //_result = sngn.Analyze() as SubNetworkResult;
            }
            else
            {
                //var inputGenes = _tbInputGenes.Text.Split(",;:\t ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToArray();
                
                //var seeds = source.Vertices.Where(x => inputGenes.Contains(x.Id.ToString()));
                //var forceSeeds = _cbAvoidLoop.IsChecked.Value;
                //var sne = new SubNetworkEnumeration(source, seeds, minNodes, maxNodes);
                //_result = sne.Analyze() as SubNetworkResult;
            }
        }

        private void ApplyGeneValue(Network network, string name)
        {
            var gvr = new GeneValueReader("C:\\Command_Console\\Data\\TCGA200\\GX\\Survival\\LEY83FEATUREGENESCORES.txt", false, 1, new char[1] { '\t' });
            var gvrd = gvr.Read();

            foreach (var gene in network.Vertices)
            {
                if (gvrd.ContainsKey(gene.Id))
                    gene.Attributes.Add(name, gvrd[gene.Id][0]);
                else
                    gene.Attributes.Add(name, 0);
            }

            gvr.Close();
        }

        #endregion
    }
}
